﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CQRSAzure.CQRSdsl.CommandLine
{
    /// <summary>
    /// A class to make sense of a CQRS model manipulation command line passed in to the command line interface
    /// </summary>
    public class CommandLineParser
    {



        /// <summary>
        /// The code languages the processor can generate code as
        /// </summary>
        public enum GenerateCodeLanguage
        {
            /// <summary>
            /// Generate code as VB.NET classes and interfaces
            /// </summary>
            /// <remarks>
            /// This is the default if not specified
            /// </remarks>
            VBNet = 0,
            /// <summary>
            /// Generate code as C# classes and interfaces
            /// </summary>
            CSharp = 1
        }

        #region Example command syntax

        public const string EXAMPLE_CREATE_MODEL = @"CREATE MODEL modelname";

        public const string EXAMPLE_CREATE_AGGREGATE = 
            @"   [USING modelname]
   ADD AGGREGATE aggregatename
   IDENTIFIED BY keyname
     AS keydatatype
    [AUTOGENERATED]";

        public const string EXAMPLE_DELETE_AGGREGATE =
            @"   [USING modelname]
    DELETE AGGREGATE aggregatename";

        public const string EXAMPLE_DOCUMENT =
            @"   [USING modelname]
   DOCUMENT [AGGREGATE | QUERY | COMMAND | EVENT | PROJECTION] objectname
      DESCRIPTION => ''
      NOTES => ''";

        public const string EXAMPLE_ADD_EVENT =
            @"   [USING modelname]
   [FOR AGGREGATE aggregatename]
   ADD EVENT eventname";

        public const string EXAMPLE_ADD_EVENT_PROPERTY =
            @"   [USING modelname]
   [FOR AGGREGATE aggregatename]
   [FOR EVENT eventname]
   ADD PROPERTY eventpropertyname
     AS datatype";

        public const string EXAMPLE_DEPRECIATE_EVENT_PROPERTY =
            @"   [USING modelname]
   [FOR AGGREGATE aggregatename]
   [FOR EVENT eventname]
   DEPRECIATE PROPERTY eventpropertyname";

        public const string EXAMPLE_INCREMENT_EVENT_VERSION =
            @"   [USING modelname]
   [FOR AGGREGATE aggregatename]
   VERSION EVENT eventname";

        public const string EXAMPLE_ADD_COMMAND =
            @"   [USING modelname]
   [FOR AGGREGATE aggregatename]
   ADD COMMAND commandname";

        public const string EXAMPLE_DELETE_COMMAND =
            @"   [USING modelname]
   [FOR AGGREGATE aggregatename]
   DELETE COMMAND commandname";

        public const string EXAMPLE_ADD_COMMAND_PROPERTY =
    @"   [USING modelname]
   [FOR AGGREGATE aggregatename]
   [FOR COMMAND commandname]
   ADD PROPERTY commandpropertyname
     AS datatype";

        public const string EXAMPLE_DELETE_COMMAND_PROPERTY =
    @"   [USING modelname]
   [FOR AGGREGATE aggregatename]
   [FOR COMMAND commandname]
   DELETE PROPERTY commandpropertyname";

        public const string EXAMPLE_REGENERATE_CODE =
            @"     [USING modelname]
    GENERATE CODE [VB.NET | C#]";

        public const string EXAMPLE_REGENERATE_DOCUMENTATION =
            @"     [USING modelname]
    GENERATE DOCUMENTATION";

        public const string EXAMPLE_USING_MODEL =   @" USING modelname";

        public const string EXAMPLE_FOR_AGGREGATE = @" FOR AGGREGATE aggregatename";

        public const string EXAMPLE_FOR_EVENT = @" FOR EVENT eventname";

        public const string EXAMPLE_FOR_COMMAND = @" FOR COMMAND commandname";

        #endregion

        #region command constants

        public const string COMMAND_CREATE = @"CREATE";

        public const string COMMAND_ADD = @"ADD";

        public const string COMMAND_DELETE = @"DELETE";

        public const string COMMAND_DEPRECIATE = @"DEPRECIATE";

        public const string COMMAND_VERSION = @"VERSION";

        public const string COMMAND_GENERATE = @"GENERATE";

        #endregion

        #region command snippet constants
        public const string COMMAND_USING = @"USING";

        public const string COMMAND_FOR = @"FOR";

        #endregion

        #region target object type constants

        public const string TARGET_MODEL = @"MODEL";

        public const string TARGET_AGGREGATE = @"AGGREGATE";

        public const string TARGET_QUERY = @"QUERY";

        public const string TARGET_COMMAND = @"COMMAND";

        public const string TARGET_EVENT = @"EVENT";

        public const string TARGET_PROJECTION = @"PROJECTION";

        public const string TARGET_CODE = @"CODE";

        public const string TARGET_DOCUMENTATION = @"DOCUMENTATION";

        #endregion


        public IModelModificationCommand ParseCommand(string commandLine)
        {
            // If we get here we didn't know what to make of the command
            return new NullModelModificationCommand(commandLine ); 
        }
    }
}
